概述
本节继续完成课程详情页面的样式调整,涵盖三个核心部分:Swiper 的 activeIndex 绑定、UnoCSS shortcuts 中按钮样式的封装,以及详情页整体布局的精细化调整(背景分区、Tabs 激活态、课程描述省略、底部登录/搜索栏等)。
1. Swiper activeIndex 绑定
在课程详情的轮播组件中,需要将当前激活的幻灯片索引与组件状态绑定:
<Swiper
:active-index="activeIndex"
@change="(index) => activeIndex = index"
>
<!-- slides -->
</Swiper>
vue
通过 activeIndex 的双向绑定,可以在外部精确控制轮播位置,同时响应用户的滑动手势。
2. UnoCSS Shortcuts 封装按钮样式
2.1 配置 shortcuts
在 uno.config.ts 的 shortcuts 字段中定义可复用的按钮样式组合:
// uno.config.ts
export default defineConfig({
shortcuts: {
'btn': 'px-4 py-2 rounded cursor-pointer transition-all',
'btn-plain': 'bg-white text-gray-700 px-4 py-2 rounded hover:bg-gray-100',
'btn-primary': 'bg-sky-500 text-white px-4 py-2 rounded hover:bg-sky-600',
'btn-small': 'text-sm px-2 py-1',
'btn-large': 'text-lg px-6 py-3',
'btn-danger': 'bg-red-500 text-white hover:bg-red-600',
'btn-success': 'bg-green-500 text-white hover:bg-green-600',
'btn-info': 'bg-blue-500 text-white hover:bg-blue-600',
'btn-warning': 'bg-yellow-500 text-white hover:bg-yellow-600',
},
})
ts
2.2 在模板中使用
<button class="btn btn-primary">加入购物车</button>
<button class="btn btn-plain">收藏</button>
vue
优势:将常用的样式组合提取为语义化的 class 名称,减少模板中的重复代码,便于全局统一修改。
3. 详情页布局精细化
3.1 背景分区
详情页分为两个主要区域,各自拥有不同的背景色:
<!-- 头部:课程介绍区(白色背景) -->
<div class="bg-white py-10">
<div class="container">
<!-- 课程名称、描述、价格等 -->
</div>
</div>
<!-- 内容区(灰色背景) -->
<div class="bg-gray-100">
<div class="container">
<!-- Tabs + 内容 + 侧边栏 -->
</div>
</div>
vue
关键点:bg-white 加在外层 div 上而非 container 上,确保白色区域铺满整个屏幕宽度。container 仅限制内容区域的最大宽度(如 1200px)。
3.2 内容区左右分栏
使用 Flex 布局将左侧内容区(3/4)与右侧边栏(1/4)分离:
<div class="flex">
<!-- 左侧:Tabs + 课程内容 -->
<div class="w-3/4 bg-white mr-4 px-4 py-2">
<!-- tabs -->
</div>
<!-- 右侧:边栏 -->
<div class="bg-white">
<div class="mb-2 h-20">推荐课程 1</div>
<div class="mb-2 h-20">推荐课程 2</div>
</div>
</div>
vue
边栏内部各条目使用 mb-2 保持一致的间距。
3.3 Tabs 激活态样式
Tabs 的激活状态通过 CSS 伪类 ::after 实现底部高亮线:
/* Tabs 激活态 */
.tab-item {
@apply relative px-4 py-2 cursor-pointer;
}
.tab-item.active {
@apply text-sky-400;
}
.tab-item.active::after {
content: '';
@apply absolute bottom-0 left-1/2 -translate-x-1/2 w-full h-0.5 bg-sky-400;
}
css
替代 calc() 的居中方案:left-1/2 -translate-x-1/2 利用 Tailwind/UnoCSS 的 transform 类实现等价效果。
3.4 课程描述省略
当课程描述过长时,使用 line-clamp 进行多行省略:
<p class="line-clamp-3 text-gray-300 text-sm">
{{ course.description }}
</p>
vue
| 属性 | 说明 |
|---|---|
line-clamp-2 | 限制为 2 行后省略 |
line-clamp-3 | 限制为 3 行后省略 |
| 兼容性 | 主要在 WebKit 内核浏览器支持 |
注意:使用 line-clamp 时不能同时使用 overflow-hidden 的 padding 方案,应改用 margin-bottom 控制间距。
3.5 按钮交互优化
<button class="btn btn-primary mr-2 cursor-pointer hover:opacity-90">
加入购物车
</button>
<button class="btn btn-plain cursor-pointer hover:bg-gray-400 hover:text-white">
收藏
</button>
vue
cursor-pointer:鼠标悬停显示手型光标hover:系列类:控制悬停时的视觉反馈mr-2:按钮间的间距
4. 底部登录/搜索栏
4.1 结构
<div class="absolute bottom-0 left-0 w-full bg-gray-800 py-4 z-10">
<div class="container flex justify-between items-center text-white">
<!-- 左侧:分类 -->
<div class="flex items-center gap-2">
<span class="tab-item active">每日一课</span>
<span class="tab-item">精品微课</span>
<span class="tab-item">学习计划</span>
<span class="tab-item">优质专栏</span>
</div>
<!-- 右侧:搜索 + 登录 -->
<div class="flex items-center">
<div class="flex items-center bg-white rounded-md px-4">
<input
type="text"
placeholder="搜索课程"
class="outline-none w-full pl-4 pr-2"
/>
<span class="iconify" data-icon="ep:search"></span>
</div>
<div class="ml-4 flex">
<span class="cursor-pointer text-gray-100 hover:text-white mr-2">登录</span>
<span class="cursor-pointer text-gray-100 hover:text-white ml-2">注册</span>
</div>
</div>
</div>
</div>
vue
4.2 分类 Tabs 样式
分类 Tabs 使用独立的 CSS 命名空间避免与内容区 Tabs 冲突:
/* 底部分类 */
.nav-tab {
@apply px-4 py-1 rounded-md bg-white/20 text-sm cursor-pointer
hover:bg-white hover:text-gray-800;
}
.nav-tab.active {
@apply bg-white text-gray-800;
}
css
命名隔离策略:内容区的 Tabs 使用 .tab-item 命名,底部分类使用 .nav-tab 命名,确保样式不冲突。
4.3 搜索框细节
outline-none:移除输入框聚焦时的默认轮廓线pl-4 pr-2:左侧留出较大内边距供文字输入,右侧缩小间距贴紧搜索图标- 整体使用
bg-white rounded-md实现白色圆角容器
5. 响应式说明
本节实现的样式主要针对 PC 端。当页面缩小后,搜索区域和登录区域需要做响应式调整(隐藏或重排),这部分将在后续的响应式布局章节中处理。
小结
| 模块 | 关键技术 |
|---|---|
| 按钮封装 | UnoCSS shortcuts 语义化组合 |
| 背景分区 | 外层 div + bg- 控制全屏背景 |
| Tabs 激活态 | ::after 伪元素 + left-1/2 -translate-x-1/2 |
| 文本省略 | line-clamp-* 多行截断 |
| 底部浮层 | absolute + z-10 层级控制 |
| 搜索框 | Flex 布局 + outline-none 输入优化 |
↑